package com.sword.springboot.web.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.sword.springboot.bean.User;
import com.sword.springboot.service.UserService;

@Controller
@RequestMapping(value="/")
public class LoginController {
	
	private static final Logger logger = Logger.getLogger(LoginController.class);

	@Autowired
	private UserService userService;
	
	@Autowired
	private HashedCredentialsMatcher hashedCredentialsMatcher;

	/**
	 * 项目入口
	 * @return
	 * author sword
	 * 2017年4月20日 上午9:04:20
	 */
	@RequestMapping(value="/enter")
	public String enter() {
		System.out.println("welcome to you.");
		return "redirect:login.jsp";
	}
	
	/**
	 * 用户注册
	 * @param username	用户名，非空
	 * @param password	密码，非空
	 * @param mail		邮箱
	 * @param model
	 * @return
	 * author sword
	 * 2017年4月20日 上午9:11:29
	 */
	@RequestMapping(value="/signUp.do")
	@ResponseBody
	public Map<String, Object> signUp(String username, String password, String mail,String tnc, Model model ){
		Map<String, Object> map = new HashMap<>();
		map.put("res", false);
		if(tnc == null || !tnc.equals("on")){
			map.put("msg", "请确认你同意协议！");
		}
		
		if(username == null || password == null || username.trim().equals("") || password.trim().equals("")){
			//model.addAttribute("msg", "账号或密码不能为空！");
			map.put("msg", "账号密码不能为空！");
		}
		
		if(mail == null || mail.trim().equals("")){
			mail = "";
		}
		
		Integer result = 0;
		try {
			result = userService.addNewUser(new User(username, password, mail));
		} catch (Exception e) {
			map.put("msg", "用户名已存在！");
		}
		if(result > 0){
			map.put("res", true);
			map.put("msg", "注册成功！");
		}else {
			map.put("msg", "注册失败！");
		}
		return map;
	}
	
	/**
	 * 用户登录
	 * @param username
	 * @param password
	 * @param redirectAttributes
	 * @return
	 * author sword
	 * 2017年4月20日 下午3:02:46
	 */
	@RequestMapping(value="/login.do")
	public String login(String username, String password, RedirectAttributes redirectAttributes, HttpSession session) {
		
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		//获取当前的subject
		Subject currentUser = SecurityUtils.getSubject();
		try {
            //在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查  
            //每个Realm都能在必要时对提交的AuthenticationTokens作出反应  
            //所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法  
            
            System.out.println("对用户[" + username + "]进行登录验证..验证开始");
            currentUser.login(token);  
              
            System.out.println("对用户[" + username + "]进行登录验证..验证通过");
        }catch(UnknownAccountException uae){  
            
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
            redirectAttributes.addFlashAttribute("message", "未知账户");  
        }catch(IncorrectCredentialsException ice){  
            
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
            redirectAttributes.addFlashAttribute("message", "密码不正确");  
        }catch(LockedAccountException lae){  
             
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
            redirectAttributes.addFlashAttribute("message", "账户已锁定");  
        }catch(ExcessiveAttemptsException eae){  
             
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
            redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数过多");  
        }catch(AuthenticationException ae){  
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景  
             
            System.out.println("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
            ae.printStackTrace();  
            redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");  
        }  
        //验证是否登录成功  
        if(currentUser.isAuthenticated()){  
            
            System.out.println("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
            session.setAttribute("username", token.getUsername());
            return "redirect:index.jsp";
        }else{  
            token.clear();  
            return "login";
        }
	}
	
	@RequestMapping(value="/logout")  
    public String logout(RedirectAttributes redirectAttributes ){ 
        //使用权限管理工具进行用户的退出，跳出登录，给出提示信息
        SecurityUtils.getSubject().logout();  
        redirectAttributes.addFlashAttribute("message", "您已安全退出");  
        return "login";
    } 

    @RequestMapping("/403")
    public String unauthorizedRole(){
        
        System.out.println("------没有权限-------");
        return "403";
    }

    /*@RequestMapping("/user")
    public String getUserList(Map<String, Object> model){
        model.put("userList", userService.get);
        return "user";
    }*/

    /*@RequestMapping("/user/edit/{userid}")
    public String getUserList(@PathVariable int userid){
        logger.info("------进入用户信息修改-------");
        return "user_edit";
    }*/
}
